﻿using System.Collections.Generic;
using PsqlDotnet.Enums;
using PsqlDotnet.Model;
using PsqlDotnet.Model.Schema;

namespace PsqlDotnet
{
    public interface IPsqlShell
    {
        string PsqlPath { get; }
        string AdminLogin { get; }
        string AdminPassword { get; }

        /// <summary>
        /// Execute custom script using psql
        /// </summary>
        void ExecuteScript(string script, string dbName);
        /// <summary>
        /// Gets psql version
        /// </summary>
        string GetVersion();
        /// <summary>
        /// Gets value indicating whether database with given name exists
        /// </summary>
        bool DatabaseExists(string dbName);
        /// <summary>
        /// Gets information about database with given name. 
        /// If there is no such a database returns null
        /// </summary>
        DbInfo GetDatabaseInfo(string dbName);
        /// <summary>
        /// Gets information about all known databases
        /// </summary>
        IEnumerable<DbInfo> GetDatabasesInfo();
        /// <summary>
        /// Creates new database with given name. On any error or if database already exists exception is thrown
        /// </summary>
        void CreateDatabase(string dbName, string ownerName);
        /// <summary>
        /// Removes database with given name. On any error or if database doesn't exist exception is thrown
        /// </summary>
        void DropDatabase(string dbName);

        bool UserExists(string userName);
        IEnumerable<DbUserInfo> GetAllUsers();
        void CreateUserIfNotExists(string userName, string plainPassword, UserPermissionFlags options);
        void CreateUser(string userName, string plainPassword, UserPermissionFlags options);
        void ChangePassword(string userName, string newPlainPassword);
        void ChangeUserPermissions(string userName, UserPermissionFlags newOptions);
        void DropUser(string userName);

        IEnumerable<DbGroup> GetAllGroups();
        void CreateGroup(string groupName);
        void DropGroup(string groupName);
        void AddUserToGroup(string groupName, string userName);
        void RemoveUserFromGroup(string groupName, string userName);

        void GrantPrivilegesToUser(string userName, string objectName, DbPrivileges flags);
        void RevokePrivilegesFromUser(string userName, string objectName, DbPrivileges flags);
        void GrantPrivilegesToGroup(string groupName, string objectName, DbPrivileges flags);
        void RevokePrivilegesFromGroup(string groupName, string objectName, DbPrivileges flags);
        void GrantPublicPrivileges(string objectName, DbPrivileges flags);
        void RevokePublicPrivileges(string objectName, DbPrivileges flags);

        string[] GetTableNames(string dbName);
        ITable GetTableSchema(string dbName, string tableName);
        void CreateTable(string dbName, ITable table);
    }
}
